﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace HSIA
{
    public class MyReceiver
    {
        public MyReceiver(DatabaseObject dbo, DataRow drReceiver)
        {
            this.dbo = dbo;

            RefreshParam(drReceiver);

            DataTable dtAccount = dbo.GetDataTableBySql("select * from sys_Account where Company_Code ='" + drReceiver["Company_Code"].ToString().Trim() + "'", "Account");
            if (dtAccount != null && dtAccount.Rows.Count > 0) drAccount = dtAccount.Rows[0];
            else return;

            sDB_Name = drAccount["DB_Name"].ToString();

            strConn = string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3};",
                drAccount["IP"], sDB_Name, drAccount["DB_User"], drAccount["DB_Password"]);

            RefreshSensor();
            isConnected = true;

            sUpate += "Where KeyId='" + sReceiverKeyID + "'";
        }

        private DatabaseObject dbo;

        public DataRow drAccount;
        public DataRow drReceiver;
        public DataTable dtSensor;
        public DataTable dtGatherData;
        public IntPtr frmHandle;
        //public int iReceiverId;

        public string sReceiverKeyID;
        public int iReceiverKeyID;
        public int DevType;
        public string sVersion;
        public int SensorCount;
        public Int16 TimeZone = 0;
        public Int16 SendCycle = 0;
        public Int16 RFCycle = 0;

        public string IP;
        public bool isConnected = false;
        private string sDB_Name;

        private string strConn = "";
        private string sUpate = "Update Sys_Receiver set {0} ";

        public void RefreshParam(DataRow _dr)
        {
            this.drReceiver = _dr;
            int.TryParse(drReceiver["DeviceType"].ToString(), out DevType);
            short.TryParse(drReceiver["SendCycle"].ToString(), out SendCycle);
            short.TryParse(drReceiver["RFCycle"].ToString(), out RFCycle);
            short.TryParse(drReceiver["TimeZone"].ToString(), out TimeZone);

            sReceiverKeyID = drReceiver["KeyId"].ToString();
            int.TryParse(sReceiverKeyID, out iReceiverKeyID);

        }

        /// <summary>
        /// 判断传感器是否存在并返回对应的行
        /// </summary>
        /// <param name="iSensorID"></param>
        /// <param name="drSensor"></param>
        /// <returns></returns>
        public bool IsExistSensor(int iSensorID, out DataRow drSensor)
        {
            if (dtSensor == null)
            {
                drSensor = null;
                return false;
            }
            else
            {
                drSensor = dtSensor.Rows.Find(new object[] { sReceiverKeyID, iSensorID });
                return drSensor != null;
            }
        }

        /// <summary>
        /// 判断传感器是否存在
        /// </summary>
        /// <param name="iSensorID"></param>
        /// <returns></returns>
        public bool IsExistSensor(int iSensorID)
        {
            if (dtSensor == null)
            {
                return false;
            }
            else
            {
                DataRow drSensor = dtSensor.Rows.Find(new object[] { sReceiverKeyID, iSensorID });
                return drSensor != null;
            }
        }

        /// <summary>
        /// 判断当前批次的数据是否存在
        /// </summary>
        /// <param name="sGatherNo"></param>
        /// <returns></returns>
        public bool IsExistData(string sGatherNo)
        {
            DataTable dt = dbo.GetDataTableBySql("select count(ID) CNT from Sys_GatherData where GatherDate='" + sGatherNo + "' and  ReceiverId= '" + sReceiverKeyID + "'", "GatherData");
            return Convert.ToInt32(dt.Rows[0]["CNT"]) > 0;
        }

        /// <summary>
        /// 判断指定传感器是否有重复数据
        /// </summary>
        /// <param name="sGatherDate"></param>
        /// <param name="iSensorID"></param>
        /// <returns></returns>
        public bool IsExistData(string sGatherDate, int iSensorID)
        {
            DateTime date;
            DataRow drSensor;
            if (DateTime.TryParse(sGatherDate, out date) && IsExistSensor(iSensorID, out drSensor))
            {
                //int frequency = -PublicMethod.GetInt(drSensor["Frequency"], 5) + 1;
                string sql = string.Format("select count(KeyID) CNT from Sys_GatherData where GatherDate='{0}' and ReceiverId={1} and SensorID={2}",
                    date.ToString(PublicFunc.sDateFormat), sReceiverKeyID, iSensorID);
                DataTable dt = dbo.GetDataTableBySql(sql, "GatherData", strConn);
                return Convert.ToInt32(dt.Rows[0]["CNT"]) > 0;
            }
            else return true;
        }


        /// <summary>
        /// 获取时钟
        /// </summary>
        /// <param name="iTimeZone"></param>
        /// <param name="date"></param>
        public void SetDateTime(short iTimeZone, string date)
        {
            string str = dbo.ExcuteSQL(string.Format(sUpate, "TimeZone='" + iTimeZone + "'"));
            if (str == "OK")
            {
                drReceiver["GatherFrequency"] = date;
                drReceiver["TimeZone"] = TimeZone = iTimeZone;
            }

        }

        public string[] GetDateTime()
        {
            string sDate = DateTime.Now.ToUniversalTime().ToString("yyMMddHHmmss");
            string[] sOrder = new string[7];
            sOrder[0] = Convert.ToInt32(TimeZone).ToString("X2");
            for (int i = 0; i < sDate.Length; i += 2)
            {
                sOrder[(i / 2) + 1] = Convert.ToInt32(sDate.Substring(i, 2)).ToString("X2");
            }
            return sOrder;
        }

        /// <summary>
        /// 获取周期
        /// </summary>
        /// <param name="iRFCycle"></param>
        /// <param name="iSendCycle"></param>
        public void SetCycle(short iRFCycle, short iSendCycle)
        {
            string sql = "Update Sys_Receiver set RFCycle='" + iRFCycle + "',SendCycle='" + iSendCycle + "'";
            string str = dbo.ExcuteSQL(sql);
            if (str == "OK")
            {
                drReceiver["RFCycle"] = RFCycle = iRFCycle;
                drReceiver["SendCycle"] = SendCycle = iSendCycle;
            }
        }

        public string[] GetCycle()
        {
            string[] sOrder = new string[2];
            sOrder[0] = PublicFunc.GetSmallEnd(Convert.ToInt16(RFCycle), 4);
            sOrder[1] = PublicFunc.GetSmallEnd(Convert.ToInt16(SendCycle), 4);
            return sOrder;
        }

        /// <summary>
        /// 获取参数信息
        /// </summary>
        /// <param name="iDevType"></param>
        /// <param name="sVersion"></param>
        public void SetInfo(int iDevType, string sVersion)
        {
            string str = dbo.ExcuteSQL(string.Format(sUpate, "DeviceType='" + iDevType + "',Version='" + sVersion + "'"));
            if (str == "OK")
            {
                drReceiver["DeviceType"] = DevType = iDevType;
                drReceiver["Version"] = this.sVersion = sVersion;
            }
        }

        /// <summary>
        /// 匹配传感器
        /// </summary>
        /// <param name="sSensorIds"></param>
        public void MateSensor(string sSensorIds)
        {
            string sql = "Update Sys_Receiver set SensorIds='" + sSensorIds + "'";
            string str = dbo.ExcuteSQL(sql);
            if (str == "OK")
            {
                drReceiver["SensorIds"] = sSensorIds;
            }
        }

        /// <summary>
        /// 注册传感器type：0默认数据库，1手动设置
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public string[] GetSensor(byte type)
        {
            string[] sOrder = new string[] { };
            if (type == 0)
            {
                RefreshSensor();
                sOrder = new string[SensorCount];
                for (int i = 0; i < SensorCount; i++)
                {
                    DataRow dr = dtSensor.Rows[i];
                    sOrder[i] = dr["SensorId"].ToString();
                }
            }
            else if (type == 1)
            {
                string[] sSensorIds = GetSensor(0);
                sOrder = new string[sSensorIds.Length + 1];
                sOrder[0] = PublicFunc.GetSmallEnd(Convert.ToInt16(sSensorIds.Length), 4);
                for (int i = 1; i < sOrder.Length; i++)
                {
                    int iSensorId = 0;
                    if (int.TryParse(sSensorIds[i - 1], out iSensorId))
                        sOrder[i] = BitConverter.ToString(BitConverter.GetBytes(iSensorId), 0).Replace("-", "");
                }
            }
            return sOrder;
        }

        /// <summary>
        /// 获取阈值
        /// </summary>
        /// <param name="ExistFlag"></param>
        /// <param name="byteHex"></param>
        public void SetThreshold(string sExistFlag, byte[] byteHex)
        {
            string sKey = "", sValue = "";
            int index = 0;
            string sql = "";
            DataTable dt = dbo.GetDataTableBySql("Select count(KeyId) From Sys_Receiver_Threshold Where KeyId='" + sReceiverKeyID + "'", "Sys_Receiver_Threshold");
            if (dt != null && Convert.ToInt32(dt.Rows[0][0]) > 0)
                sql = "Update Sys_Receiver_Threshold set {0} Where KeyId='" + sReceiverKeyID + "'";
            else
                sql = "Insert Into Sys_Receiver_Threshold(KeyId,{0}) values('" + sReceiverKeyID + "',{1})";
            DataRow[] drM = dbo.dtMeasureType.Select("Tag>" + 0);
            drReceiver.BeginEdit();
            foreach (DataRow dr in drM)
            {
                try
                {
                    int FieldIndex = Convert.ToInt32(dr["FieldIndex"]) - 1;
                    if (sExistFlag[FieldIndex] == '1')
                    {
                        int iValue = Convert.ToInt32(dr["Tag"]);
                        string sKeyId = "U" + dr["ID"];
                        Int32 idata = BitConverter.ToInt16(byteHex, index);
                        string sData = (idata / iValue).ToString(); index += 2;
                        if (idata == 0x7FFF) sData = "NULL";
                        if (sql.StartsWith("Update")) sKey += sKeyId + "=" + sData + ",";
                        else sKey += sKeyId + ",";
                        sValue += "'" + sData + "',";
                        drReceiver[sKeyId] = sData;

                        sKeyId = "L" + dr["ID"];
                        idata = BitConverter.ToInt16(byteHex, index);
                        sData = (idata / iValue).ToString(); index += 2;
                        if (idata == 0x8000) sData = "NULL";
                        if (sql.StartsWith("Update")) sKey += sKeyId + "=" + sData + ",";
                        else sKey += sKeyId + ",";
                        sValue += "'" + sData + "',";
                        drReceiver[sKeyId] = sData;
                    }
                }
                catch (Exception)
                {
                }
            }
            string str = dbo.ExcuteSQL(string.Format(sql, sKey.TrimEnd(','), sValue.TrimEnd(',')));
            if (str != "OK")
            {
                drReceiver.CancelEdit();
            }
            drReceiver.EndEdit();
        }

        public string[] GetThreshold(bool IsImmediateAlarm)
        {
            string sOrders = string.Empty;
            //DataRow[] drM = dbo.dtMeasureType.Select("Tag>" + 0);
            string sExistFlag = drReceiver["Tag"].ToString();
            sOrders += PublicFunc.GetSmallEnd(Convert.ToInt16(sExistFlag, 2), 4);
            string sql = "select SensorId,UpperValue,LowerValue from Sys_Device_Threshold{0} where HandleCode='abs' and ReceiverId={1} order by SensorId";
            DataTable Threshold1 = dbo.GetDataTableBySql(string.Format(sql, 1, iReceiverKeyID), "Threshold", strConn);
            Threshold1.PrimaryKey = new DataColumn[] { Threshold1.Columns["SensorId"] };
            DataTable Threshold2 = dbo.GetDataTableBySql(string.Format(sql, 2, iReceiverKeyID), "Threshold", strConn);
            Threshold2.PrimaryKey = new DataColumn[] { Threshold2.Columns["SensorId"] };
            if (IsImmediateAlarm)
            {
                sOrders += SensorCount.ToString("X2");
                foreach (var item in GetSensor(0))
                {
                    sOrders += PublicFunc.GetSmallEnd(Convert.ToInt32(item), 8);
                    DataRow dr = null;
                    int ratio = 0;
                    if (sExistFlag[sExistFlag.Length - 2] == '1')//湿度  
                    {
                        dr = Threshold2.Rows.Find(item);
                        ratio = 10;
                        if (dr != null) sOrders += PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["UpperValue"]) * ratio), 4) + PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["LowerValue"]) * ratio), 4);
                        else sOrders += 0XFF7F.ToString("X4") + 0X0080.ToString("X4");
                    }
                    if (sExistFlag[sExistFlag.Length - 1] == '1')//温度                
                    {
                        dr = Threshold1.Rows.Find(item);
                        ratio = 8;
                        if (dr != null) sOrders += PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["UpperValue"]) * ratio), 4) + PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["LowerValue"]) * ratio), 4);
                        else sOrders += 0XFF7F.ToString("X4") + 0X0080.ToString("X4");
                    }
                }
            }
            else
            {
                sOrders += "01" + PublicFunc.GetSmallEnd(Convert.ToInt32(0), 8);
                DataRow dr = drReceiver;
                int ratio = 0;
                if (sExistFlag[sExistFlag.Length - 2] == '1')//湿度  
                {
                    ratio = 10;
                    if (dr.Table.Columns.Contains("UH")) sOrders += PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["UH"]) * ratio), 4) + PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["LH"]) * ratio), 4);
                    else sOrders += 0XFF7F.ToString("X4") + 0X0080.ToString("X4");
                }
                if (sExistFlag[sExistFlag.Length - 1] == '1')//温度                
                {
                    ratio = 8;
                    if (dr.Table.Columns.Contains("UT")) sOrders += PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["UT"]) * ratio), 4) + PublicFunc.GetSmallEnd((short)(Convert.ToInt16(dr["LT"]) * ratio), 4);
                    else sOrders += 0XFF7F.ToString("X4") + 0X0080.ToString("X4");
                }
            }
            return new string[] { sOrders };
        }


        /// <summary>
        /// 刷新传感器信息
        /// </summary>
        public void RefreshSensor()
        {
            dtSensor = dbo.GetDataTableBySql("select ReceiverId,SensorId,MeasureTypeId,Frequency,IsImmediateAlarm from Sys_Device where ReceiverId=" + sReceiverKeyID + " order by SensorId", "Sensor", strConn);
            dtSensor.PrimaryKey = new DataColumn[] { dtSensor.Columns["ReceiverId"], dtSensor.Columns["SensorId"] };
            SensorCount = dtSensor.Rows.Count;
        }

        /// <summary>
        /// 刷新接收器状态
        /// </summary>
        /// <param name="sKeyId"></param>
        /// <param name="sPort"></param>
        public void RefreshReceiver(string sPort)
        {
            string sql = "";
            //if (drReceiver["KeyId"].ToString() != sKeyId)
            //{
            //    sql += "KeyId='" + sKeyId + "',";
            //    drReceiver["KeyId"] = sKeyId;
            //}
            if (drReceiver["Port"].ToString().IndexOf(":") == -1 && drReceiver["Port"].ToString() != sPort)
            {
                sql += "Port='" + sPort + "',ConnectType=0,";
                drReceiver["Port"] = sPort;
            }
            if (sql != "") dbo.ExcuteSQL("update Sys_Receiver set " + sql.TrimEnd(',') + " where KeyId=" + sReceiverKeyID);

            //if (sReceiverKeyID != sKeyId) sReceiverKeyID = sKeyId;

            if (drReceiver["Online"].ToString() != dbo.GetLanguage(195) && drReceiver["Port"].ToString().StartsWith(sPort))
                drReceiver["Online"] = dbo.GetLanguage(195);//"在线";"在线"
        }

        /// <summary>
        /// 刷新接收器采集时间休息
        /// </summary>
        public void RefreshGatherDate()
        {
            drReceiver["GatherFrequency"] = DateTime.Now.ToString();
        }

        /// <summary>
        /// 运行报表储存过程
        /// </summary>
        public void RefreshDayReport()
        {
            if (!isConnected) return;
            dbo.ExcuteSQL("procDeviceRunning", strConn);
            dbo.ExcuteSQL("procHandleReasons", strConn);
            dbo.ExcuteSQL("procAbnormalWeek", strConn);
            dbo.ExcuteSQL("procHandleStatsWeek", strConn);
            dbo.ExcuteSQL("procAbnormalMonth", strConn);
            dbo.ExcuteSQL("procHandleStatsMonth", strConn);
        }


        private void SetDorpData(string sGatherNo)
        {
            string sSql = "select ID from Sys_Device where ReceiverId=" + sReceiverKeyID + " and ID not in (select ID from Sys_GatherData where GatherNo='" + sGatherNo + "');";
            DataTable dt = dbo.GetDataTableBySql(sSql, strConn);
            if (dt != null && dt.Rows.Count > 0)
            {
                sSql = "";
                foreach (DataRow dr in dt.Rows)
                {
                    sSql += "insert into Sys_NoGatherData(ReceiverId,SensorId,GatherNo) values('" + sReceiverKeyID + "','" + dr["Id"] + "','" + sGatherNo + "');";
                }
                if (sSql != "") dbo.ExcuteSQL(sSql);
            }
            //""insert into Sys_GatherNo(GatherNo) values('" + sGatherNo + "');";
        }

        /// <summary>
        /// 存储数据到账套
        /// </summary>
        /// <param name="sGatherData"></param>
        /// <param name="sGatherNo"></param>
        /// <param name="sKeyId"></param>
        /// <param name="sPort"></param>
        public void WirteData(string sGatherData, string sGatherNo, string sPort)
        {
            if (!isConnected) return;
            CleanMapData();
            string str = dbo.ExcuteSQL(sGatherData, strConn);
            if (str == "OK")
            {
                dtGatherData = dbo.GetDataTableBySql("select * from Sys_GatherData where GatherDate is not null and ReceiverId=" + sReceiverKeyID + " and GatherNo='" + sGatherNo + "'", "Sys_GatherData", strConn);
                RefreshGatherDate();
            }
            else dtGatherData = null;

            ProcessWarningData.ProcessData(dbo, sReceiverKeyID, sGatherNo, strConn);
        }

        /// <summary>
        /// 清除实时列表设备数据
        /// </summary>
        public void CleanMapData()
        {
            if (!isConnected) return;
            string sql = string.Format("UPDATE Sys_Map SET State='D0',PARA_1={1},PARA_2={1},B={1},S={1},WarnMeasure={1},WarnType={1},SentStatus={1} WHERE ReceiverId={0} and GatherDate<'{2}'", sReceiverKeyID, "NULL", DateTime.Now.AddMinutes(-5).ToString());
            dbo.ExcuteSQL(sql, strConn);
        }

        /// <summary>
        /// 删除接收器对应的全部数据
        /// </summary>
        /// <returns></returns>
        public bool DeleteData()
        {
            if (!isConnected) return false;
            FrmUserCheck fuc = new FrmUserCheck(dbo, strConn);
            if (fuc.ShowDialog() != System.Windows.Forms.DialogResult.OK) return false;
            string sql = string.Format("Delete From Sys_Device Where ReceiverId='{0}';" +
                "Delete From Sys_Map Where ReceiverId='{0}';Delete From Sys_Map_B Where ReceiverId='{0}';" +
                "Delete From Sys_GatherData Where ReceiverId='{0}';Delete From Sys_GatherData_B Where ReceiverId='{0}';" +
                "Delete From Sys_WarnData Where ReceiverId='{0}';Delete From Sys_WarnData_B Where ReceiverId='{0}';", iReceiverKeyID);
            if (dbo.ExcuteSQL(sql, strConn) == "OK")
            {
                return dbo.ExcuteSQL("Delete From Sys_Receiver Where KeyId='" + sReceiverKeyID + "';") == "OK";
            }
            else return false;
        }

        public static string[] GetDeviceInfo(DatabaseObject dbo, int receiverId, int sensorId, string constr)
        {
            //            string sql = @"select a.DepartmentId,b.Mobile,c.Mobile mobile2,d.Mobile mobile3 from Sys_Device a 
            //left join Sys_Users b on a.UserId=b.KeyId
            //left join Sys_Users c on a.UserId2=c.KeyId
            //left join Sys_Users d on a.UserId3=d.KeyId where a.ReceiverId={0} and a.SensorId={1} ";
            //            DataTable dt = dbo.GetDataTableBySql(string.Format(sql, receiverId, sensorId), "Device", constr);
            //            string[] data = new string[2];
            //            if (dt != null && dt.Rows.Count > 0)
            //            {
            //                string mobile = PublicMethod.GetString(dt.Rows[0]["Mobile"]);
            //                string mobile2 = PublicMethod.GetString(dt.Rows[0]["mobile2"]);
            //                string mobile3 = PublicMethod.GetString(dt.Rows[0]["mobile3"]);

            //                data[0] = mobile + ";" + mobile2 + ";" + mobile3;
            //                //data[0] = dt.Rows[0]["Mobile"].ToString();
            //                string sDepartmentId = dt.Rows[0]["DepartmentId"].ToString();
            //                GetParent(dbo, sDepartmentId, ref data[1], constr);
            //            }
            //            return data;

            string sql = @"select DepartmentId,UserId from Sys_Device where ReceiverId={0} and SensorId={1}";

            DataTable dt = dbo.GetDataTableBySql(string.Format(sql, receiverId, sensorId), "Device", constr);

            string[] data = new string[2];

            if (dt != null && dt.Rows.Count > 0)
            {
                string userIds = PublicMethod.GetString(dt.Rows[0]["UserId"]);

                string mobileList = string.Empty;

                sql = string.Format(@"with t as (select 1 keyId,Mobile from Sys_Users where CHARINDEX(KeyId,'{0}')>0 and IsAdmin='false')
select mobile=STUFF((select ';'+Mobile from t where t.KeyId=t1.KeyId FOR XML PATH ('')),1,1,'') from t t1
group by keyId", userIds);

                DataTable dtMobile = dbo.GetDataTableBySql(sql, "MobileList", constr);

                data[0] = PublicMethod.GetString(dtMobile.Rows[0]["mobile"]);
                string sDepartmentId = dt.Rows[0]["DepartmentId"].ToString();
                GetParent(dbo, sDepartmentId, ref data[1], constr);
            }

            return data;
        }

        public static void GetParent(DatabaseObject dbo, string parentID, ref string depName, string constr)
        {
            DataTable dt = dbo.GetDataTableBySql("select ParentId,DepartmentName from Sys_Departments where KeyId='" + parentID + "'", "Department", constr);

            if (dt != null && dt.Rows.Count > 0)
            {
                DataRow dr = dt.Rows[0];
                if (dr["ParentId"].ToString() != "0")
                    depName = "[" + dr["DepartmentName"] + "]-" + depName;
                GetParent(dbo, dr["ParentId"].ToString(), ref depName, constr);
            }
        }
    }
}
